package cn.unknowpupil.init.service.system.impl;

import cn.unknowpupil.init.common.constant.SecurityConstants;
import cn.unknowpupil.init.domain.dto.LoginUser;
import cn.unknowpupil.init.domain.dto.MenuNode;
import cn.unknowpupil.init.domain.dto.MetaVo;
import cn.unknowpupil.init.domain.system.SysPermission;
import cn.unknowpupil.init.domain.system.SysRole;
import cn.unknowpupil.init.domain.system.SysUser;
import cn.unknowpupil.init.domain.dto.TreeSelect;
import cn.unknowpupil.init.mapper.system.SysRoleMapper;
import cn.unknowpupil.init.service.system.ISysPermissionService;
import cn.unknowpupil.init.mapper.system.SysPermissionMapper;
import cn.unknowpupil.init.utils.security.SecurityUtils;
import cn.unknowpupil.init.utils.strings.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import io.jsonwebtoken.lang.Assert;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created at 2020-11-13 by  w10g <br>
 * Initialize SysPermission  ... <br>
 * 权限表 核心业务处理实现类
 *
 * @author unknowpupil
 * @since 0.0.1
 */
@Service
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements ISysPermissionService {


    @Resource
    private SysRoleMapper roleMapper;

    /**
     * 新增
     *
     * @param permission {@link SysPermission}  权限表
     * @return {@link SysPermission}
     */
    @Override
    public boolean create(SysPermission permission) {
        if (permission.getPid() != null && permission.getPid() > 0) {
            SysPermission parent = baseMapper.selectById(permission.getPid());
            permission.setFullId(parent.getFullId() + '-' + parent.getId());
        } else {
            permission.setFullId("0");
        }
        return save(permission);
    }

    /**
     * 详情
     *
     * @param id {@code Long}   SysPermission ID
     * @return {@link SysPermission}
     */
    @Override
    public SysPermission info(Long id) {
        return getById(id);
    }

    /**
     * 删除
     *
     * @param id {@code Long}   ids
     * @return {@link SysPermission}
     */
    @Override
    public boolean delete(Long id) {
// todo:删除所有下级 权限菜单。
        return removeById(id);
    }


    /**
     * 修改
     *
     * @param permission {@link SysPermission}  权限表
     * @return {@link SysPermission}
     */
    @Override
    public boolean update(SysPermission permission) {
        if (permission.getPid() != null && permission.getPid() > 0) {
            SysPermission parent = baseMapper.selectById(permission.getPid());
            permission.setFullId(parent.getFullId() + '-' + parent.getId());
        } else {
            permission.setFullId("0");
        }
        return updateById(permission);
    }


    @Override
    public Set<String> selectMenuPermsByUserId(Long id) {
        List<String> perms = baseMapper.selectMenuPermsByUserId(id);
        Set<String> permsSet = new HashSet<>();
        for (String perm : perms) {
            if (StringUtils.isNotEmpty(perm)) {
                permsSet.addAll(Arrays.asList(perm.trim().split(",")));
            }
        }
        return permsSet;
    }

    @Override
    public List<SysPermission> selectPermissionList(SysPermission permission, LoginUser loginUser) {

        List<SysPermission> permissionList = null;
        if (SysUser.isAdmin(loginUser.getPid())) {
            LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
            if (StringUtils.isNotBlank(permission.getName())) {
                wrapper.like(SysPermission::getName, permission.getName());
            }
            if (StringUtils.isNotBlank(permission.getStatus())) {
                wrapper.eq(SysPermission::getStatus, permission.getStatus());
            }
            wrapper.orderByAsc(SysPermission::getPid, SysPermission::getShowOrder);
            permissionList = baseMapper.selectList(wrapper);
        } else {
            permissionList = baseMapper.selectPermissionListByUserId(permission, loginUser.getId());
        }

        return permissionList;
    }

    @Override
    public List<SysPermission> selectPermissionList(LoginUser loginUser) {
        return selectPermissionList(new SysPermission(), loginUser);
    }

    @Override
    public List<TreeSelect> buildPermissionTreeSelect(List<SysPermission> permissions) {
        List<SysPermission> menuTrees = buildPermissionTree(permissions);
        return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());

    }

    @Override
    public List<Long> selectPermissionListByRoleId(Long roleId) {
        SysRole role = roleMapper.selectById(roleId);
        // 数据库 1代表true 0代表false
        return baseMapper.selectPermissionListByRoleId(roleId, true);
    }

    @Override
    public boolean deleteAllPermissionByRole(Long id) {
        return baseMapper.deleteAllPermissionByRole(id) > 0 ? true : false;
    }

    @Override
    public boolean insertRolePermission(Long id, Long[] permissionIds) {

        return baseMapper.insertRolePermission(id, permissionIds) > 0 ? true : false;
    }

    @Override
    public int countRolePermission(Long id) {
        return baseMapper.countRolePermission(id);
    }

    @Override
    public List<SysPermission> getPermissionList() {
        return super.list(new LambdaQueryWrapper<SysPermission>().eq(SysPermission::getStatus, 0));
    }

    @Override
    public Map<String, Object> selectMenuTreeByUserId(LoginUser loginUser) {
        Map<String, Object> map = Maps.newHashMap();
        List<SysPermission> resList = null;
        if (SecurityUtils.isAdmin(loginUser.getPid())) {
            //  如果在这里返回权限
            List<SysPermission> sysMenus = baseMapper.selectMenuTreeAll();
            // 排查按钮级别的
            List<SysPermission> meuns = sysMenus.stream().filter(o -> !o.getMenuType().equals("1")).collect(Collectors.toList());
            // 按钮权限
            Set<String> perms = new HashSet<String>();
            perms.add("*:*:*");
            map.put("permissions", perms);
            resList = meuns;
        } else {
            List<SysPermission> sysMenus = baseMapper.selectMenuTreeByUserId(loginUser.getId());
            List<SysPermission> meuns = sysMenus.stream().filter(o -> !o.getMenuType().equals("1")).collect(Collectors.toList());
            Set<String> permissions = sysMenus.stream().filter(o -> o.getMenuType().equals("1")).map(o -> o.getCode()).collect(Collectors.toSet());
            map.put("permissions", permissions);
            resList = meuns;
        }
        List<MenuNode> treeList = new ArrayList<>();
        MenuNode newNode;
        for (SysPermission node : resList) {
            if (node.getPid() == 0) {
                newNode = new MenuNode(node.getId(), node.getPid(), StringUtils.capitalize(node.getPath()));

                MetaVo metaVo = new MetaVo(node.getName(), node.getIconClass(), node.getIsCache().equals("1"));
                newNode.setMeta(metaVo);

                newNode.setRedirect(SecurityConstants.NO_REDIRECT);
                newNode.setComponent("Layout");
                newNode.setAlwaysShow(true);
                newNode.setPath("/" + node.getPath());
                newNode.setHidden(node.getHiddenFlag().equals(1 + "") ? true : false);
                treeList.add(findChildrenWithAuth(newNode, resList));
            }
        }
        map.put("menus", treeList);
        return map;
    }


    /**
     * 递归构造树结构
     *
     * @param parentNode
     * @param resList
     * @return
     */
    private MenuNode findChildrenWithAuth(MenuNode parentNode, List<SysPermission> resList) {
        MenuNode newNode;
        for (SysPermission menu : resList) {
            if (menu.getPid().equals(parentNode.getId())) {
                if (parentNode.getChildren() == null) {
                    parentNode.setChildren(new ArrayList<>());
                }
                newNode = new MenuNode(menu.getId(), menu.getPid(), StringUtils.capitalize(menu.getPath()));
                newNode.setMeta(new MetaVo(menu.getName(), menu.getIconClass(), menu.getIsCache().equals("1")));
                newNode.setComponent(menu.getComponent());
                newNode.setPath(menu.getPath());
                newNode.setHidden(menu.getHiddenFlag().equals(1 + "") ? true : false);
                MenuNode tempNode = findChildrenWithAuth(newNode, resList);
                parentNode.getChildren().add(tempNode);
            }
        }
        return parentNode;
    }


    private List<SysPermission> buildPermissionTree(List<SysPermission> permissions) {
        List<SysPermission> returnList = new ArrayList<SysPermission>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysPermission dept : permissions) {
            tempList.add(dept.getId());
        }
        for (Iterator<SysPermission> iterator = permissions.iterator(); iterator.hasNext(); ) {
            SysPermission permission = (SysPermission) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(permission.getPid())) {
                recursionFn(permissions, permission);
                returnList.add(permission);
            }
        }
        if (returnList.isEmpty()) {
            returnList = permissions;
        }
        return returnList;


    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<SysPermission> list, SysPermission t) {
        // 得到子节点列表
        List<SysPermission> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysPermission tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    private boolean hasChild(List<SysPermission> list, SysPermission tChild) {
        return getChildList(list, tChild).size() > 0 ? true : false;
    }

    /**
     * 得到子节点列表
     */
    private List<SysPermission> getChildList(List<SysPermission> list, SysPermission permission) {
        List<SysPermission> tlist = new ArrayList<SysPermission>();
        Iterator<SysPermission> it = list.iterator();
        while (it.hasNext()) {
            SysPermission n = (SysPermission) it.next();
            if (n.getPid().longValue() == permission.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

}
